using MediatR;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.PurchasingManagement.PurchaseReturns;
using Microsoft.Extensions.Logging;
using RBAC.Domain.WarehouseManagement;
using System.Transactions;
using Dapper;
using System.Linq;
using System.Text.Json;
using System;

namespace RBAC.Write.Api.Application.Handler.ERP.PurchasingManagement.PurchaseReturns
{
    public class AddPurchaseReturnCommandHandler : IRequestHandler<AddPurchaseReturnCommands, APIResult<int>>
    {
        private readonly ILogger<AddPurchaseReturnCommandHandler> _logger;
        private readonly IBaseRepository<PurchaseReturn> _returnRepository;
        private readonly IDbConnectionFactory _connectionFactory;

        public AddPurchaseReturnCommandHandler(
            ILogger<AddPurchaseReturnCommandHandler> logger,
            IBaseRepository<PurchaseReturn> returnRepository,
            IDbConnectionFactory connectionFactory)
        {
            _logger = logger;
            _returnRepository = returnRepository;
            _connectionFactory = connectionFactory;
        }

        public Task<APIResult<int>> Handle(AddPurchaseReturnCommands request, CancellationToken cancellationToken)
        {
            var result = new APIResult<int>();

            if (request == null || request.Return == null)
            {
                result.Code = APIEnums.Fail;
                result.Msg = "参数不能为空";
                result.Data = 0;
                return Task.FromResult(result);
            }

            try
            {
                var entity = request.Return;

                // 基础校验
                if (string.IsNullOrWhiteSpace(entity.DocumentCode))
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "单据编码不能为空";
                    result.Data = 0;
                    return Task.FromResult(result);
                }

                using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    // 基础字段
                    entity.CreateTime = DateTime.Now;
                    entity.IsDeleted = false;

                    // 1. 新增主表
                    var newId = _returnRepository.Create(entity);
                    if (newId <= 0)
                    {
                        throw new InvalidOperationException("新增采购退货单失败，返回的ID无效");
                    }

                    // 2. 批量插入物料
                    if (request.Materials != null && request.Materials.Any())
                    {
                        using var conn = _connectionFactory.CreateConnectionWithRetry();
                        foreach (var m in request.Materials)
                        {
                            m.PurchaseReturnId = newId;
                        }

                        try
                        {
                            var sample = request.Materials.FirstOrDefault();
                            _logger.LogInformation("AddPurchaseReturn: newId={NewId}, firstMaterial={Material}", newId, sample != null ? JsonSerializer.Serialize(sample) : "null");
                        }
                        catch (Exception logEx)
                        {
                            _logger.LogWarning(logEx, "日志序列化物料失败");
                        }

                        const string insertSql = @"INSERT INTO PurchaseReturnMaterial
                            (PurchaseReturnId, OrderNumber, MaterialCode, MaterialName, ModelSpecifications, MainMeasurement, BatchNumber, `Number`, OutboundQuantity, ReturnInstructions, IsDel)
                            VALUES
                            (@PurchaseReturnId, @OrderNumber, @MaterialCode, @MaterialName, @ModelSpecifications, @MainMeasurement, @BatchNumber, @Number, @OutboundQuantity, @ReturnInstructions, @IsDel);";

                        var affected = conn.Execute(insertSql, request.Materials);
                        if (affected != request.Materials.Count)
                        {
                            throw new InvalidOperationException($"批量新增退货物料失败：预期 {request.Materials.Count} 条，实际 {affected} 条");
                        }
                    }

                    scope.Complete();

                    result.Code = APIEnums.Success;
                    result.Msg = "新增成功";
                    result.Data = newId;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "新增采购退货单失败: {Message}", ex.Message);
                result.Code = APIEnums.Fail;
                result.Msg = "新增失败：" + ex.Message;
                result.Data = 0;
            }

            return Task.FromResult(result);
        }
    }
}
